home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #11 / Amiga Plus CD - 2004 - No. 11.iso / AmiSoft / Comm / www / tidy_os4.lha / tidy / src / lexer.h < prev    next >
C/C++ Source or Header  |  2004-07-25  |  16KB  |  579 lines

  1. #ifndef __LEXER_H__
  2. #define __LEXER_H__
  3.  
  4. /* lexer.h -- Lexer for html parser
  5.   
  6.    (c) 1998-2004 (W3C) MIT, ERCIM, Keio University
  7.    See tidy.h for the copyright notice.
  8.   
  9.    CVS Info:
  10.     $Author: hoehrmann $ 
  11.     $Date: 2004/03/08 14:42:25 $ 
  12.     $Revision: 1.19 $ 
  13.  
  14. */
  15.  
  16. /*
  17.   Given an input source, it returns a sequence of tokens.
  18.  
  19.      GetToken(source) gets the next token
  20.      UngetToken(source) provides one level undo
  21.  
  22.   The tags include an attribute list:
  23.  
  24.     - linked list of attribute/value nodes
  25.     - each node has 2 NULL-terminated strings.
  26.     - entities are replaced in attribute values
  27.  
  28.   white space is compacted if not in preformatted mode
  29.   If not in preformatted mode then leading white space
  30.   is discarded and subsequent white space sequences
  31.   compacted to single space characters.
  32.  
  33.   If XmlTags is no then Tag names are folded to upper
  34.   case and attribute names to lower case.
  35.  
  36.  Not yet done:
  37.     -   Doctype subset and marked sections
  38. */
  39.  
  40. #ifdef __cplusplus
  41. extern "C" {
  42. #endif
  43.  
  44. #include "forward.h"
  45.  
  46. /* lexer character types
  47. */
  48. #define digit       1
  49. #define letter      2
  50. #define namechar    4
  51. #define white       8
  52. #define newline     16
  53. #define lowercase   32
  54. #define uppercase   64
  55.  
  56.  
  57. /* node->type is one of these values
  58. */
  59. #define RootNode        0
  60. #define DocTypeTag      1
  61. #define CommentTag      2
  62. #define ProcInsTag      3
  63. #define TextNode        4
  64. #define StartTag        5
  65. #define EndTag          6
  66. #define StartEndTag     7
  67. #define CDATATag        8
  68. #define SectionTag      9
  69. #define AspTag          10
  70. #define JsteTag         11
  71. #define PhpTag          12
  72. #define XmlDecl         13
  73.  
  74.  
  75.  
  76. /* lexer GetToken states
  77. */
  78. #define LEX_CONTENT     0
  79. #define LEX_GT          1
  80. #define LEX_ENDTAG      2
  81. #define LEX_STARTTAG    3
  82. #define LEX_COMMENT     4
  83. #define LEX_DOCTYPE     5
  84. #define LEX_PROCINSTR   6
  85. #define LEX_ENDCOMMENT  7
  86. #define LEX_CDATA       8
  87. #define LEX_SECTION     9
  88. #define LEX_ASP         10
  89. #define LEX_JSTE        11
  90. #define LEX_PHP         12
  91. #define LEX_XMLDECL     13
  92.  
  93. /* ParseDocTypeDecl state constants */
  94. #define DT_INTERMEDIATE 0
  95. #define DT_DOCTYPENAME  1
  96. #define DT_PUBLICSYSTEM 2
  97. #define DT_QUOTEDSTRING 3
  98. #define DT_INTSUBSET    4
  99.  
  100. /* content model shortcut encoding
  101. */
  102. #define CM_UNKNOWN      0
  103. #define CM_EMPTY        (1 << 0)
  104. #define CM_HTML         (1 << 1)
  105. #define CM_HEAD         (1 << 2)
  106. #define CM_BLOCK        (1 << 3)
  107. #define CM_INLINE       (1 << 4)
  108. #define CM_LIST         (1 << 5)
  109. #define CM_DEFLIST      (1 << 6)
  110. #define CM_TABLE        (1 << 7)
  111. #define CM_ROWGRP       (1 << 8)
  112. #define CM_ROW          (1 << 9)
  113. #define CM_FIELD        (1 << 10)
  114. #define CM_OBJECT       (1 << 11)
  115. #define CM_PARAM        (1 << 12)
  116. #define CM_FRAMES       (1 << 13)
  117. #define CM_HEADING      (1 << 14)
  118. #define CM_OPT          (1 << 15)
  119. #define CM_IMG          (1 << 16)
  120. #define CM_MIXED        (1 << 17)
  121. #define CM_NO_INDENT    (1 << 18)
  122. #define CM_OBSOLETE     (1 << 19)
  123. #define CM_NEW          (1 << 20)
  124. #define CM_OMITST       (1 << 21)
  125.  
  126. /* If the document uses just HTML 2.0 tags and attributes described
  127. ** it as HTML 2.0 Similarly for HTML 3.2 and the 3 flavors of HTML 4.0.
  128. ** If there are proprietary tags and attributes then describe it as
  129. ** HTML Proprietary. If it includes the xml-lang or xmlns attributes
  130. ** but is otherwise HTML 2.0, 3.2 or 4.0 then describe it as one of the
  131. ** flavors of Voyager (strict, loose or frameset).
  132. */
  133.  
  134. /* unknown */
  135. #define xxxx                   0u
  136.  
  137. /* W3C defined HTML/XHTML family document types */
  138. #define HT20                   1u
  139. #define HT32                   2u
  140. #define H40S                   4u
  141. #define H40T                   8u
  142. #define H40F                  16u
  143. #define H41S                  32u
  144. #define H41T                  64u
  145. #define H41F                 128u
  146. #define X10S                 256u
  147. #define X10T                 512u
  148. #define X10F                1024u
  149. #define XH11                2048u
  150. #define XB10                4096u
  151.  
  152. /* proprietary stuff */
  153. #define VERS_SUN            8192u
  154. #define VERS_NETSCAPE      16384u
  155. #define VERS_MICROSOFT     32768u
  156.  
  157. /* special flag */
  158. #define VERS_XML           65536u
  159.  
  160. /* compatibility symbols */
  161. #define VERS_UNKNOWN       (xxxx)
  162. #define VERS_HTML20        (HT20)
  163. #define VERS_HTML32        (HT32)
  164. #define VERS_HTML40_STRICT (H40S|H41S|X10S)
  165. #define VERS_HTML40_LOOSE  (H40T|H41T|X10T)
  166. #define VERS_FRAMESET      (H40F|H41F|X10F)
  167. #define VERS_XHTML11       (XH11)
  168. #define VERS_BASIC         (XB10)
  169.  
  170. /* meta symbols */
  171. #define VERS_HTML40        (VERS_HTML40_STRICT|VERS_HTML40_LOOSE|VERS_FRAMESET)
  172. #define VERS_IFRAME        (VERS_HTML40_LOOSE|VERS_FRAMESET)
  173. #define VERS_LOOSE         (VERS_HTML20|VERS_HTML32|VERS_IFRAME)
  174. #define VERS_EVENTS        (VERS_HTML40|VERS_XHTML11)
  175. #define VERS_FROM32        (VERS_HTML32|VERS_HTML40)
  176. #define VERS_FROM40        (VERS_HTML40|VERS_XHTML11|VERS_BASIC)
  177. #define VERS_XHTML         (X10S|X10T|X10F|XH11|XB10)
  178.  
  179. /* all W3C defined document types */
  180. #define VERS_ALL           (VERS_HTML20|VERS_HTML32|VERS_FROM40)
  181.  
  182. /* all proprietary types */
  183. #define VERS_PROPRIETARY   (VERS_NETSCAPE|VERS_MICROSOFT|VERS_SUN)
  184.  
  185. /* Linked list of class names and styles
  186. */
  187. struct _Style;
  188. typedef struct _Style TagStyle;
  189.  
  190. struct _Style
  191. {
  192.     tmbstr tag;
  193.     tmbstr tag_class;
  194.     tmbstr properties;
  195.     TagStyle *next;
  196. };
  197.  
  198.  
  199. /* Linked list of style properties
  200. */
  201. struct _StyleProp;
  202. typedef struct _StyleProp StyleProp;
  203.  
  204. struct _StyleProp
  205. {
  206.     tmbstr name;
  207.     tmbstr value;
  208.     StyleProp *next;
  209. };
  210.  
  211.  
  212.  
  213.  
  214. /* Attribute/Value linked list node
  215. */
  216.  
  217. struct _AttVal
  218. {
  219.     AttVal*           next;
  220.     const Attribute*  dict;
  221.     Node*             asp;
  222.     Node*             php;
  223.     int               delim;
  224.     tmbstr            attribute;
  225.     tmbstr            value;
  226. };
  227.  
  228.  
  229.  
  230. /*
  231.   Mosaic handles inlines via a separate stack from other elements
  232.   We duplicate this to recover from inline markup errors such as:
  233.  
  234.      <i>italic text
  235.      <p>more italic text</b> normal text
  236.  
  237.   which for compatibility with Mosaic is mapped to:
  238.  
  239.      <i>italic text</i>
  240.      <p><i>more italic text</i> normal text
  241.  
  242.   Note that any inline end tag pop's the effect of the current
  243.   inline start tag, so that </b> pop's <i> in the above example.
  244. */
  245. struct _IStack
  246. {
  247.     IStack*     next;
  248.     const Dict* tag;        /* tag's dictionary definition */
  249.     tmbstr      element;    /* name (NULL for text nodes) */
  250.     AttVal*     attributes;
  251. };
  252.  
  253.  
  254. /* HTML/XHTML/XML Element, Comment, PI, DOCTYPE, XML Decl,
  255. ** etc. etc.
  256. */
  257.  
  258. struct _Node
  259. {
  260.     Node*       parent;         /* tree structure */
  261.     Node*       prev;
  262.     Node*       next;
  263.     Node*       content;
  264.     Node*       last;
  265.  
  266.     AttVal*     attributes;
  267.     const Dict* was;            /* old tag when it was changed */
  268.     const Dict* tag;            /* tag's dictionary definition */
  269.  
  270.     tmbstr      element;        /* name (NULL for text nodes) */
  271.  
  272.     uint        start;          /* start of span onto text array */
  273.     uint        end;            /* end of span onto text array */
  274.     uint        type;           /* TextNode, StartTag, EndTag etc. */
  275.  
  276.     uint        line;           /* current line of document */
  277.     uint        column;         /* current column of document */
  278.  
  279.     Bool        closed;         /* true if closed by explicit end tag */
  280.     Bool        implicit;       /* true if inferred */
  281.     Bool        linebreak;      /* true if followed by a line break */
  282.  
  283. #ifdef TIDY_STORE_ORIGINAL_TEXT
  284.     tmbstr      otext;
  285. #endif
  286. };
  287.  
  288.  
  289. /*
  290.   The following are private to the lexer
  291.   Use NewLexer() to create a lexer, and
  292.   FreeLexer() to free it.
  293. */
  294.  
  295. struct _Lexer
  296. {
  297. #if 0  /* Move to TidyDocImpl */
  298.     StreamIn* in;           /* document content input */
  299.     StreamOut* errout;      /* error output stream */
  300.  
  301.     uint badAccess;         /* for accessibility errors */
  302.     uint badLayout;         /* for bad style errors */
  303.     uint badChars;          /* for bad character encodings */
  304.     uint badForm;           /* for mismatched/mispositioned form tags */
  305.     uint warnings;          /* count of warnings in this document */
  306.     uint errors;            /* count of errors */
  307. #endif
  308.  
  309.     uint lines;             /* lines seen */
  310.     uint columns;           /* at start of current token */
  311.     Bool waswhite;          /* used to collapse contiguous white space */
  312.     Bool pushed;            /* true after token has been pushed back */
  313.     Bool insertspace;       /* when space is moved after end tag */
  314.     Bool excludeBlocks;     /* Netscape compatibility */
  315.     Bool exiled;            /* true if moved out of table */
  316.     Bool isvoyager;         /* true if xmlns attribute on html element */
  317.     uint versions;          /* bit vector of HTML versions */
  318.     int  doctype;           /* version as given by doctype (if any) */
  319.     Bool bad_doctype;       /* e.g. if html or PUBLIC is missing */
  320.     uint txtstart;          /* start of current node */
  321.     uint txtend;            /* end of current node */
  322.     uint state;             /* state of lexer's finite state machine */
  323.  
  324.     Node* token;            /* current parse point */
  325.     Node* root;             /* remember root node of the document */
  326.     Node* parent;           /* remember parent node for CDATA elements */
  327.     
  328.     Bool seenEndBody;       /* true if a </body> tag has been encountered */
  329.     Bool seenEndHtml;       /* true if a </html> tag has been encountered */
  330.  
  331.     /*
  332.       Lexer character buffer
  333.  
  334.       Parse tree nodes span onto this buffer
  335.       which contains the concatenated text
  336.       contents of all of the elements.
  337.  
  338.       lexsize must be reset for each file.
  339.     */
  340.     tmbstr lexbuf;          /* MB character buffer */
  341.     uint lexlength;         /* allocated */
  342.     uint lexsize;           /* used */
  343.  
  344.     /* Inline stack for compatibility with Mosaic */
  345.     Node* inode;            /* for deferring text node */
  346.     IStack* insert;         /* for inferring inline tags */
  347.     IStack* istack;
  348.     uint istacklength;      /* allocated */
  349.     uint istacksize;        /* used */
  350.     uint istackbase;        /* start of frame */
  351.  
  352.     TagStyle *styles;          /* used for cleaning up presentation markup */
  353.  
  354. #if 0
  355.     TidyDocImpl* doc;       /* Pointer back to doc for error reporting */
  356. #endif 
  357. };
  358.  
  359.  
  360. /* Lexer Functions
  361. */
  362. Node *CommentToken( Lexer *lexer );
  363.  
  364. /* choose what version to use for new doctype */
  365. int HTMLVersion( TidyDocImpl* doc );
  366.  
  367. ctmbstr GetFPIFromVers(uint vers);
  368.  
  369. /* everything is allowed in proprietary version of HTML */
  370. /* this is handled here rather than in the tag/attr dicts */
  371.  
  372. void ConstrainVersion( TidyDocImpl* doc, uint vers );
  373.  
  374. Bool IsWhite(uint c);
  375. Bool IsDigit(uint c);
  376. Bool IsLetter(uint c);
  377. Bool IsNewline(uint c);
  378. Bool IsNamechar(uint c);
  379. Bool IsXMLLetter(uint c);
  380. Bool IsXMLNamechar(uint c);
  381.  
  382. Bool IsLower(uint c);
  383. Bool IsUpper(uint c);
  384. uint ToLower(uint c);
  385. uint ToUpper(uint c);
  386.  
  387. char FoldCase( TidyDocImpl* doc, tmbchar c, Bool tocaps );
  388.  
  389.  
  390. Lexer* NewLexer( TidyDocImpl* doc );
  391. Bool EndOfInput( TidyDocImpl* doc );
  392. void FreeLexer( TidyDocImpl* doc );
  393.  
  394. /* store character c as UTF-8 encoded byte stream */
  395. void AddCharToLexer( Lexer *lexer, uint c );
  396.  
  397. /*
  398.   Used for elements and text nodes
  399.   element name is NULL for text nodes
  400.   start and end are offsets into lexbuf
  401.   which contains the textual content of
  402.   all elements in the parse tree.
  403.  
  404.   parent and content allow traversal
  405.   of the parse tree in any direction.
  406.   attributes are represented as a linked
  407.   list of AttVal nodes which hold the
  408.   strings for attribute/value pairs.
  409. */
  410. Node* NewNode( Lexer* lexer );
  411.  
  412.  
  413. /* used to clone heading nodes when split by an <HR> */
  414. Node *CloneNode( TidyDocImpl* doc, Node *element );
  415.  
  416. /* free node's attributes */
  417. void FreeAttrs( TidyDocImpl* doc, Node *node );
  418.  
  419. /* doesn't repair attribute list linkage */
  420. void FreeAttribute( TidyDocImpl* doc, AttVal *av );
  421.  
  422. /* remove attribute from node then free it
  423. */
  424. void RemoveAttribute( TidyDocImpl* doc, Node *node, AttVal *attr );
  425.  
  426. /*
  427.   Free document nodes by iterating through peers and recursing
  428.   through children. Set next to NULL before calling FreeNode()
  429.   to avoid freeing peer nodes. Doesn't patch up prev/next links.
  430.  */
  431. void FreeNode( TidyDocImpl* doc, Node *node );
  432.  
  433. Node* TextToken( Lexer *lexer );
  434.  
  435. /* used for creating preformatted text from Word2000 */
  436. Node *NewLineNode( Lexer *lexer );
  437.  
  438. /* used for adding a   for Word2000 */
  439. Node *NewLiteralTextNode(Lexer *lexer, ctmbstr txt );
  440.  
  441. Node* CommentToken(Lexer *lexer);
  442. Node* GetCDATA( TidyDocImpl* doc, Node *container );
  443.  
  444. void AddByte( Lexer *lexer, tmbchar c );
  445. void AddStringLiteral( Lexer* lexer, ctmbstr str );
  446. void AddStringLiteralLen( Lexer* lexer, ctmbstr str, int len );
  447.  
  448. /* find element */
  449. Node* FindDocType( TidyDocImpl* doc );
  450. Node* FindHTML( TidyDocImpl* doc );
  451. Node* FindHEAD( TidyDocImpl* doc );
  452. Node* FindTITLE(TidyDocImpl* doc);
  453. Node* FindBody( TidyDocImpl* doc );
  454. Node* FindXmlDecl(TidyDocImpl* doc);
  455.  
  456. /* Returns containing block element, if any */
  457. Node* FindContainer( Node* node );
  458.  
  459. /* add meta element for Tidy */
  460. Bool AddGenerator( TidyDocImpl* doc );
  461.  
  462. /* examine <!DOCTYPE> to identify version */
  463. int FindGivenVersion( TidyDocImpl* doc, Node* doctype );
  464. int ApparentVersion( TidyDocImpl* doc );
  465.  
  466.  
  467. Bool CheckDocTypeKeyWords(Lexer *lexer, Node *doctype);
  468.  
  469. ctmbstr HTMLVersionName( TidyDocImpl* doc );
  470. ctmbstr HTMLVersionNameFromCode( uint vers, Bool isXhtml );
  471.  
  472. Bool SetXHTMLDocType( TidyDocImpl* doc );
  473.  
  474.  
  475. /* fixup doctype if missing */
  476. Bool FixDocType( TidyDocImpl* doc );
  477.  
  478. /* ensure XML document starts with <?XML version="1.0"?> */
  479. /* add encoding attribute if not using ASCII or UTF-8 output */
  480. Bool FixXmlDecl( TidyDocImpl* doc );
  481.  
  482. Node* InferredTag(TidyDocImpl* doc, TidyTagId id);
  483.  
  484. Bool ExpectsContent(Node *node);
  485.  
  486.  
  487. void UngetToken( TidyDocImpl* doc );
  488.  
  489.  
  490. /*
  491.   modes for GetToken()
  492.  
  493.   MixedContent   -- for elements which don't accept PCDATA
  494.   Preformatted   -- white space preserved as is
  495.   IgnoreMarkup   -- for CDATA elements such as script, style
  496. */
  497. #define IgnoreWhitespace    0
  498. #define MixedContent        1
  499. #define Preformatted        2
  500. #define IgnoreMarkup        3
  501. #define CdataContent        4
  502.  
  503. Node* GetToken( TidyDocImpl* doc, uint mode );
  504.  
  505. void InitMap(void);
  506.  
  507. Bool IsValidAttrName( ctmbstr attr );
  508.  
  509.  
  510. /* create a new attribute */
  511. AttVal *NewAttribute(void);
  512.  
  513. /* create a new attribute with given name and value */
  514. AttVal *NewAttributeEx(ctmbstr name, ctmbstr value);
  515.  
  516. /*************************************
  517.   In-line Stack functions
  518. *************************************/
  519.  
  520.  
  521. /* duplicate attributes */
  522. AttVal* DupAttrs( TidyDocImpl* doc, AttVal* attrs );
  523.  
  524. /*
  525.   push a copy of an inline node onto stack
  526.   but don't push if implicit or OBJECT or APPLET
  527.   (implicit tags are ones generated from the istack)
  528.  
  529.   One issue arises with pushing inlines when
  530.   the tag is already pushed. For instance:
  531.  
  532.       <p><em>text
  533.       <p><em>more text
  534.  
  535.   Shouldn't be mapped to
  536.  
  537.       <p><em>text</em></p>
  538.       <p><em><em>more text</em></em>
  539. */
  540. void PushInline( TidyDocImpl* doc, Node* node );
  541.  
  542. /* pop inline stack */
  543. void PopInline( TidyDocImpl* doc, Node* node );
  544.  
  545. Bool IsPushed( TidyDocImpl* doc, Node* node );
  546.  
  547. /*
  548.   This has the effect of inserting "missing" inline
  549.   elements around the contents of blocklevel elements
  550.   such as P, TD, TH, DIV, PRE etc. This procedure is
  551.   called at the start of ParseBlock. when the inline
  552.   stack is not empty, as will be the case in:
  553.  
  554.     <i><h1>italic heading</h1></i>
  555.  
  556.   which is then treated as equivalent to
  557.  
  558.     <h1><i>italic heading</i></h1>
  559.  
  560.   This is implemented by setting the lexer into a mode
  561.   where it gets tokens from the inline stack rather than
  562.   from the input stream.
  563. */
  564. int InlineDup( TidyDocImpl* doc, Node *node );
  565.  
  566. /*
  567.  defer duplicates when entering a table or other
  568.  element where the inlines shouldn't be duplicated
  569. */
  570. void DeferDup( TidyDocImpl* doc );
  571. Node *InsertedToken( TidyDocImpl* doc );
  572.  
  573. #ifdef __cplusplus
  574. }
  575. #endif
  576.  
  577.  
  578. #endif /* __LEXER_H__ */
  579.